001 /*
002 * Copyright 2005 Stephen J. McConnell
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
013 * implied.
014 *
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 package net.dpml.library.info;
020
021 import net.dpml.library.Feature;
022 import net.dpml.library.Resource;
023 import net.dpml.library.ResourceNotFoundException;
024 import net.dpml.library.Type;
025
026 /**
027 * Simple value filter.
028 *
029 * @author <a href="http://www.dpml.net">The Digital Product Meta Library</a>
030 * @version 1.0.0
031 */
032 public class FeatureFilterDirective extends FilterDirective
033 {
034 private final Feature m_feature;
035 private final boolean m_alias;
036 private String m_reference;
037 private String m_type;
038
039 /**
040 * Creation of a new anonymous resource directive.
041 * @param token the filter token
042 * @param ref an external resource refernce (possibly null)
043 * @param feature the resource feature
044 * @param type the resource type
045 * @param alias if the alias flag
046 */
047 public FeatureFilterDirective( String token, String ref, Feature feature, String type, boolean alias )
048 {
049 super( token );
050 m_reference = ref;
051 m_feature = feature;
052 m_type = type;
053 m_alias = alias;
054 }
055
056 /**
057 * Get the resource ref value.
058 * If null the ref shall be interprited as the enclosing project.
059 * @return the ref value
060 */
061 public String getResourceReference()
062 {
063 return m_reference;
064 }
065
066 /**
067 * Return the filter value.
068 * @param resource the enclosing resource
069 * @return the resolved value
070 * @exception ResourceNotFoundException if the feature references a
071 * resource that is unknown
072 */
073 public String getValue( Resource resource ) throws ResourceNotFoundException
074 {
075 Resource r = getReferenceResource( resource );
076 if( null == m_type )
077 {
078 return Feature.resolve( r, m_feature );
079 }
080 else
081 {
082 Type type = r.getType( m_type );
083 return Feature.resolve( r, m_feature, type, m_alias );
084 }
085
086 /*
087 if( null != m_type && !r.isa( m_type ) )
088 {
089 final String error =
090 "The feature request for the type ["
091 + m_type
092 + "] from the resource ["
093 + r
094 + "] cannot be fullfilled because the resource does not declare "
095 + "production of the requested type.";
096 throw new FeatureRuntimeException( error );
097 }
098
099 if( m_feature.equals( Feature.NAME ) )
100 {
101 return r.getName();
102 }
103 else if( m_feature.equals( Feature.GROUP ) )
104 {
105 return r.getParent().getResourcePath();
106 }
107 else if( m_feature.equals( Feature.VERSION ) )
108 {
109 String version = r.getVersion();
110 if( null == version )
111 {
112 return "";
113 }
114 else
115 {
116 return version;
117 }
118 }
119 else if( m_feature.equals( Feature.URI ) )
120 {
121 return resolveURIFeature( r );
122 }
123 else if( m_feature.equals( Feature.SPEC ) )
124 {
125 String path = r.getResourcePath();
126 String version = r.getVersion();
127 if( null == version )
128 {
129 return path;
130 }
131 else
132 {
133 return path + "#" + version;
134 }
135 }
136 else if( m_feature.equals( Feature.PATH ) )
137 {
138 if( null == m_type )
139 {
140 final String error =
141 "Type attribute must be supplied in conjuction with the uri attribute.";
142 throw new FeatureRuntimeException( error );
143 }
144 else
145 {
146 Artifact artifact = r.getArtifact( m_type );
147 try
148 {
149 File cached =
150 (File) artifact.toURL().getContent( new Class[]{File.class} );
151 return cached.getCanonicalPath();
152 }
153 catch( Exception e )
154 {
155 final String error =
156 "Unable to resolve resource path.";
157 throw new FeatureRuntimeException( error, e );
158 }
159 }
160 }
161 else if( m_feature.equals( Feature.FILENAME ) )
162 {
163 if( null == m_type )
164 {
165 final String error =
166 "Type attribute must be supplied in conjuction with the filename attribute.";
167 throw new IllegalArgumentException( error );
168 }
169 return r.getLayoutPath( m_type );
170 }
171 else
172 {
173 final String error =
174 "Invalid feature [" + m_feature + "].";
175 throw new FeatureRuntimeException( error );
176 }
177 */
178 }
179 /*
180 private String resolveURIFeature( Resource resource )
181 {
182 if( null == m_type )
183 {
184 final String error =
185 "Type attribute must be supplied in conjuction with the uri attribute.";
186 throw new FeatureRuntimeException( error );
187 }
188 else
189 {
190 if( m_alias )
191 {
192 Type type = resource.getType( m_type );
193 Version version = type.getVersion();
194 if( null != version )
195 {
196 Artifact artifact = resource.getArtifact( m_type );
197 String group = artifact.getGroup();
198 String name = artifact.getName();
199 if( Version.NULL_VERSION.equals( version ) )
200 {
201 return "link:"
202 + m_type
203 + ":"
204 + group
205 + "/"
206 + name;
207 }
208 else
209 {
210 int major = version.getMajor();
211 int minor = version.getMinor();
212 return "link:"
213 + m_type
214 + ":"
215 + group
216 + "/"
217 + name
218 + "#"
219 + major
220 + "."
221 + minor;
222 }
223 }
224 else
225 {
226 final String error =
227 "Cannot resolve link from resource ["
228 + resource
229 + "] because the resource does not declare production of an alias for the type ["
230 + type.getID()
231 + "].";
232 throw new FeatureRuntimeException( error );
233 }
234 }
235 else
236 {
237 Artifact artifact = resource.getArtifact( m_type );
238 return artifact.toURI().toASCIIString();
239 }
240 }
241 }
242 */
243
244 private Resource getReferenceResource( Resource resource ) throws ResourceNotFoundException
245 {
246 if( null == m_reference )
247 {
248 return resource;
249 }
250 else
251 {
252 return resource.getLibrary().getResource( m_reference );
253 }
254 }
255
256 /**
257 * Compare this object with another for equality.
258 * @param other the other object
259 * @return true if equal
260 */
261 public boolean equals( Object other )
262 {
263 if( super.equals( other ) && ( other instanceof FeatureFilterDirective ) )
264 {
265 FeatureFilterDirective directive = (FeatureFilterDirective) other;
266 if( !m_feature.equals( directive.m_feature ) )
267 {
268 return false;
269 }
270 else if( !m_type.equals( directive.m_type ) )
271 {
272 return false;
273 }
274 else if( !m_reference.equals( directive.m_reference ) )
275 {
276 return false;
277 }
278 else
279 {
280 return m_alias == directive.m_alias;
281 }
282 }
283 else
284 {
285 return false;
286 }
287 }
288
289 /**
290 * Compute the hash value.
291 * @return the hashcode value
292 */
293 public int hashCode()
294 {
295 int hash = super.hashCode();
296 hash ^= super.hashValue( m_feature );
297 hash ^= super.hashValue( m_reference );
298 hash ^= super.hashValue( m_type );
299 if( m_alias )
300 {
301 hash ^= 1;
302 }
303 else
304 {
305 hash ^= -1;
306 }
307 return hash;
308 }
309 }